"""This module provides the gen_compile_flags_txt_linux_amd64 macro."""

load("@skia_user_config//:copts.bzl", "DEFAULT_COPTS")
load("//toolchain:linux_amd64_toolchain_config.bzl", "EXTERNAL_TOOLCHAIN")

def _gen_compile_flags_txt_linux_amd64_rule_impl(ctx):
    # We need to set the working directory to the workspace root before invoking "bazel info
    # output_base", or Bazel will fail with "ERROR: bazel should not be called from a
    # bazel output directory.". This error is due to the fact that the script generated by this
    # rule will have its working directory set to a path under its runfiles directory.
    bazel_output_base = "$(cd $BUILD_WORKSPACE_DIRECTORY && bazel info output_base)"

    flags = [
        "-xc++",  # Treat all files as C++. Without this, clangd treats .h files as C files.
        "-I.",  # Required for includes relative to the workspace root to work.

        # Based on
        # https://skia.googlesource.com/skia/+/064f144adedd8ad8ac9c613c54e6354268041912/toolchain/linux_amd64_toolchain_config.bzl#214.
        #
        # It would be nice to have these in a constant exported by
        # //toolchain:linux_amd64_toolchain_config.bzl.
        "-isystem",
        "%s/%s/include/c++/v1" % (bazel_output_base, EXTERNAL_TOOLCHAIN),
        "-isystem",
        "%s/%s/include/x86_64-unknown-linux-gnu/c++/v1/" % (bazel_output_base, EXTERNAL_TOOLCHAIN),
        "-isystem",
        "%s/%s/usr/include" % (bazel_output_base, EXTERNAL_TOOLCHAIN),
        "-isystem",
        "%s/%s/lib/clang/18/include" % (bazel_output_base, EXTERNAL_TOOLCHAIN),
        "-isystem",
        "%s/%s/usr/include/x86_64-linux-gnu" % (bazel_output_base, EXTERNAL_TOOLCHAIN),

        # Based on
        # https://skia.googlesource.com/skia/+/064f144adedd8ad8ac9c613c54e6354268041912/toolchain/linux_amd64_toolchain_config.bzl#238.
        #
        # It would be nice to have these in a constant exported by
        # //toolchain:linux_amd64_toolchain_config.bzl.
        "-std=c++20",
        "-stdlib=libc++",
    ] + ctx.attr.flags

    script = "#!/bin/sh\n"
    for flag in flags:
        script += "echo %s\n" % flag

    output_file = ctx.actions.declare_file(ctx.attr.name)
    ctx.actions.write(output_file, script, is_executable = True)

    return [DefaultInfo(executable = output_file)]

_gen_compile_flags_txt_linux_amd64_rule = rule(
    doc = """Implements the gen_compile_flags_txt_linux_amd64 macro.

    This has to be a rule, rather than a macro, because macros do not evaluate select()
    expressions, as is the case with lists such as DEFAULT_COPTS.
    """,
    implementation = _gen_compile_flags_txt_linux_amd64_rule_impl,
    attrs = {
        "flags": attr.string_list(
            mandatory = True,
        ),
    },
    executable = True,
)

def gen_compile_flags_txt_linux_amd64(name):
    """Generates a compile_flags.txt file for use with clangd.

    See entry in //BUILD.bazel for usage instructions.
    """
    _gen_compile_flags_txt_linux_amd64_rule(
        name = name,
        flags = DEFAULT_COPTS,
    )
